package com.xinsoft.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xinsoft.common.exception.BDException;
import com.xinsoft.constant.Const;
import com.xinsoft.entity.dto.CusBreakDownRepaireDTO;
import com.xinsoft.entity.dto.CusDeviceBreakdownDTO;
import com.xinsoft.entity.dto.CusRepaireDTO;
import com.xinsoft.entity.dto.CusRepairePageParam;
import com.xinsoft.entity.po.*;
import com.xinsoft.entity.vo.CusRepaireSpareVo;
import com.xinsoft.entity.vo.CusRepaireVo;
import com.xinsoft.entity.vo.SysClientVo;
import com.xinsoft.mapper.CusRepaireMapper;
import com.xinsoft.service.*;
import com.xinsoft.utils.TokenUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
* @author hsm
* @description 针对表【cus_repaire(故障维修

维修时使用状况需要回写设备表)】的数据库操作Service实现
* @createDate 2023-06-20 16:46:12
*/
@Service
public class CusRepaireServiceImpl extends ServiceImpl<CusRepaireMapper, CusRepaire>
    implements CusRepaireService{

    @Autowired
    private CusDeviceBreakdownService cusDeviceBreakdownService;

    @Resource
    public CusDocumentService cusDocumentService;

    @Resource
    public CusDeviceService cusDeviceService;

    @Resource
    public CusRepaireSpareService cusRepaireSpareService;

    @Resource
    public SysDictionaryService sysDictionaryService;

    @Resource
    public CusRepairApproveService cusRepairApproveService;

    @Resource
    public SysUserService sysUserService;

    @Resource
    public SysFileHisService sysFileHisService;

    /**
     * 处理报修时，保存维修信息
     */
    @Override
    public CusRepaire  dealAddCusRepaire(CusRepaireDTO cusRepaireDTO) {
        CusDeviceBreakdown cusDeviceBreakdown = cusDeviceBreakdownService.getById(cusRepaireDTO.getBreakdownId());
        if (!Objects.equals(cusDeviceBreakdown.getRepaireStatus() , Const.RepairStatus.SUBMIT)) {
            // 故障报修不是提交状态，无法编辑和保存维修
            throw new BDException("操作失败，故障报修不是提交状态，无法处理维修！");
        }
        if (!Objects.equals(cusDeviceBreakdown.getRepaireUserId() , TokenUtil.getUserId())) {
            throw new BDException("操作失败，非维修负责人，无法处理维修！");
        }
        return addCusRepaire(cusRepaireDTO);
    }

    private CusRepaire  addCusRepaire(CusRepaireDTO cusRepaireDTO) {
        if(cusRepaireDTO.getRepaireStatus()==null){
            cusRepaireDTO.setRepaireStatus(Const.RepairRecordStatus.PROCESSING);
        }
        CusRepaire repair= new CusRepaire();
        BeanUtils.copyProperties(cusRepaireDTO,repair);
        //计算维修费用

        save(repair);

        //保存图片
        if(CollectionUtil.isNotEmpty(cusRepaireDTO.getCusDocumentListDocument())){
            for (CusDocument cusDocument : cusRepaireDTO.getCusDocumentListDocument()) {
                cusDocument.setDeviceRefId(repair.getId());
                cusDocument.setDeviceRefType(Const.DeviceRefType.DEVICE_REPAIR_FILE);
            }
            cusDocumentService.saveBatch(cusRepaireDTO.getCusDocumentListDocument());
        }

        // 保存使用备件
        List<CusRepaireSpare> cusRepaireSpareList = new ArrayList<>();
        CusRepaireSpare cusRepaireSpare = new CusRepaireSpare();

        BigDecimal spareTotalPrice = BigDecimal.ZERO;
        if(CollectionUtil.isNotEmpty(cusRepaireDTO.getCusRepaireSpareList())){
            for (CusRepaireSpareVo cusRepaireSpareVo : cusRepaireDTO.getCusRepaireSpareList()) {
                cusRepaireSpareVo.setRepaireId(repair.getId());
                cusRepaireSpare = new CusRepaireSpare();
                BeanUtils.copyProperties(cusRepaireSpareVo,cusRepaireSpare);
                cusRepaireSpareList.add(cusRepaireSpare);
                spareTotalPrice = spareTotalPrice.add(new BigDecimal(cusRepaireSpare.getTotalPrice()));
            }
        }
        cusRepaireSpareService.saveBatch(cusRepaireSpareList);
        //提交时同步设备使用状态；
        repair.setTotalPrice(spareTotalPrice.add(new BigDecimal(repair.getHourPrice())).doubleValue());
        updateById(repair);
        updateDeviceUseStatus(repair);
        return repair;

    }

    /**
     * 处理报修时，编辑维修信息
     */
    @Override
    public CusRepaire dealEditCusRepaire(CusRepaireDTO cusRepaireDTO) {
        CusDeviceBreakdown cusDeviceBreakdown = cusDeviceBreakdownService.getById(cusRepaireDTO.getBreakdownId());
        if (!Objects.equals(cusDeviceBreakdown.getRepaireStatus() , Const.RepairStatus.SUBMIT)) {
            // 故障报修不是提交状态，无法编辑和保存维修
            throw new BDException("操作失败，故障报修不是提交状态，无法处理维修！");
        }
        if (!Objects.equals(cusDeviceBreakdown.getRepaireUserId() , TokenUtil.getUserId())) {
            throw new BDException("操作失败，非维修负责人，无法处理维修！");
        }

        return editCusRepaire(cusRepaireDTO);
    }

    /**
     * 暂存维修信息
     * @param cusRepaireDTO
     * @return
     */
    private CusRepaire editCusRepaire(CusRepaireDTO cusRepaireDTO) {

        if(cusRepaireDTO.getRepaireStatus()==null){
            cusRepaireDTO.setRepaireStatus(Const.RepairRecordStatus.PROCESSING);
        }
        CusRepaire repair= new CusRepaire();
        BeanUtils.copyProperties(cusRepaireDTO,repair);
        repair.setId(cusRepaireDTO.getId());
        updateById(repair);


        //删除图片关系
        QueryWrapper queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("device_ref_id",repair.getId());
        queryWrapper.eq("device_ref_type",Const.DeviceRefType.DEVICE_REPAIR_FILE);
        cusDocumentService.remove(queryWrapper);
        //保存图片
        if(CollectionUtil.isNotEmpty(cusRepaireDTO.getCusDocumentListDocument())){
            for (CusDocument cusDocument : cusRepaireDTO.getCusDocumentListDocument()) {
                cusDocument.setDeviceRefId(repair.getId());
                cusDocument.setDeviceRefType(Const.DeviceRefType.DEVICE_REPAIR_FILE);
            }
            cusDocumentService.saveBatch(cusRepaireDTO.getCusDocumentListDocument());
        }

        // 删除使用备件
        QueryWrapper spareQueryWrapper = new QueryWrapper<>();
        spareQueryWrapper.eq("repaire_id",repair.getId());
        cusRepaireSpareService.remove(spareQueryWrapper);

        // 保存使用备件
        List<CusRepaireSpare> cusRepaireSpareList = new ArrayList<>();
        CusRepaireSpare cusRepaireSpare = new CusRepaireSpare();
        BigDecimal spareTotalPrice = BigDecimal.ZERO;
        if(CollectionUtil.isNotEmpty(cusRepaireDTO.getCusRepaireSpareList())){
            for (CusRepaireSpareVo cusRepaireSpareVo : cusRepaireDTO.getCusRepaireSpareList()) {
                cusRepaireSpareVo.setRepaireId(repair.getId());
                cusRepaireSpare = new CusRepaireSpare();
                BeanUtils.copyProperties(cusRepaireSpareVo,cusRepaireSpare);
                cusRepaireSpareList.add(cusRepaireSpare);
                spareTotalPrice = spareTotalPrice.add(new BigDecimal(cusRepaireSpare.getTotalPrice()));
            }
        }
        cusRepaireSpareService.saveBatch(cusRepaireSpareList);
        //更新总金额
        repair.setTotalPrice(spareTotalPrice.add(new BigDecimal(repair.getHourPrice())).doubleValue());
        updateById(repair);

        //提交时同步设备使用状态；
        updateDeviceUseStatus(repair);
        return repair;

    }

    /**
     * 添加报修和维修记录
     * @param cusBreakDownRepaireDTO
     * @return
     */
    @Override
    public CusRepaire addCusBreakDownRepaireRecord(CusBreakDownRepaireDTO cusBreakDownRepaireDTO) {
        CusRepaire repair = new CusRepaire();
        // 保存维修

        if(cusBreakDownRepaireDTO.getCusRepaireDTO()!=null){
            cusBreakDownRepaireDTO.getCusRepaireDTO().setBreakdownId(cusBreakDownRepaireDTO.getCusDeviceBreakdownDTO().getId());
            repair = this.addCusRepaire(cusBreakDownRepaireDTO.getCusRepaireDTO());
        }


        if(cusBreakDownRepaireDTO.getCusDeviceBreakdownDTO().getRepaireStatus()==null){
            //设置报修状态为暂存
            cusBreakDownRepaireDTO.getCusDeviceBreakdownDTO().setRepaireStatus(Const.RepairStatus.STAGING);
        }
        CusDeviceBreakdown cusDeviceBreakdown;
        if(cusBreakDownRepaireDTO.getCusDeviceBreakdownDTO().getId()==null){
            // 保存故障报修
            cusDeviceBreakdown = cusDeviceBreakdownService.addCusDeviceBreakdown(cusBreakDownRepaireDTO.getCusDeviceBreakdownDTO());
        }else{
            // 更新故障报修
            cusDeviceBreakdown = cusDeviceBreakdownService.editCusDeviceBreakdown(cusBreakDownRepaireDTO.getCusDeviceBreakdownDTO());
        }

        repair.setBreakdownId(cusDeviceBreakdown.getId());
        updateById(repair);


        return repair;
    }


    /**
     * 修改报修和维修记录
     * @param cusBreakDownRepaireDTO
     * @return
     */
    @Override
    public CusRepaire editCusBreakDownRepaireRecord(CusBreakDownRepaireDTO cusBreakDownRepaireDTO) {

        // 更新维修
        CusRepaire repair = new CusRepaire();
        // 保存维修
        if(cusBreakDownRepaireDTO.getCusRepaireDTO()!=null){
            cusBreakDownRepaireDTO.getCusRepaireDTO().setBreakdownId(cusBreakDownRepaireDTO.getCusDeviceBreakdownDTO().getId());
            repair = this.editCusRepaire(cusBreakDownRepaireDTO.getCusRepaireDTO());
        }

        if(cusBreakDownRepaireDTO.getCusDeviceBreakdownDTO().getRepaireStatus()==null){
            //设置报修状态为暂存
            cusBreakDownRepaireDTO.getCusDeviceBreakdownDTO().setRepaireStatus(Const.RepairStatus.STAGING);
        }
        // 更新故障报修
        CusDeviceBreakdown cusDeviceBreakdown = cusDeviceBreakdownService.editCusDeviceBreakdown(cusBreakDownRepaireDTO.getCusDeviceBreakdownDTO());

        return repair;

    }

    @Override
    public CusRepaireVo getCusRepaire(Integer id) {
        CusRepaire repair = this.getById(id);
        if (repair==null){
            return null;
        }
        CusRepaireVo cusRepaireVo = new CusRepaireVo();
        BeanUtils.copyProperties(repair,cusRepaireVo);
        cusRepaireVo.setId(repair.getId());
        cusRepaireVo.setUseStatusName(sysDictionaryService.getById(repair.getUseStatus()).getDicName());
        cusRepaireVo.setCusRepairApproveDTO(cusRepairApproveService.getRepairApproveByBreakDownId(repair.getBreakdownId()));

        //获取备件列表
        List<CusRepaireSpareVo> cusRepaireSpareVoList =  cusRepaireSpareService.findListByParam(id);
        cusRepaireVo.setCusRepaireSpareList(cusRepaireSpareVoList);


        //照片列表
        QueryWrapper queryWrapper2 = new QueryWrapper<>();
        queryWrapper2.select("document_id");
        queryWrapper2.eq("device_ref_id",repair.getId());
        queryWrapper2.eq("device_ref_type",Const.DeviceRefType.DEVICE_REPAIR_FILE);
        List<CusDocument> documentList2 = cusDocumentService.list(queryWrapper2);
        cusRepaireVo.setCusDocumentListDocument(documentList2);
        // 图片列表
        if(CollectionUtil.isNotEmpty(documentList2)){
            List<Integer> fileIds = documentList2.stream()
                    .map(CusDocument::getDocumentId)
                    .collect(Collectors.toList());
            QueryWrapper queryFileWrapper = new QueryWrapper<>();
            queryFileWrapper.in("id",fileIds);
            List<SysFileHis> fileHisList = sysFileHisService.list(queryFileWrapper);
            cusRepaireVo.setSysFileHisList(fileHisList);
        }


        return cusRepaireVo;
    }

    @Override
    public CusBreakDownRepaireDTO getCusBreakDownRepaire(Integer id) {
        CusRepaire repair = this.getById(id);
        if (repair==null){
            return null;
        }

        CusBreakDownRepaireDTO cusBreakDownRepaireDTO = new CusBreakDownRepaireDTO();

        CusDeviceBreakdownDTO cusDeviceBreakdownDTO = new CusDeviceBreakdownDTO();
        CusDeviceBreakdown entity = cusDeviceBreakdownService.getById(repair.getBreakdownId());
        BeanUtils.copyProperties(entity,cusDeviceBreakdownDTO);
        cusBreakDownRepaireDTO.setCusDeviceBreakdownDTO(cusDeviceBreakdownDTO);
        //获取设备
        CusDevice device = cusDeviceService.getById(entity.getDeviceId());
        cusDeviceBreakdownDTO.setDeviceNo(device.getDeviceNo());
        cusDeviceBreakdownDTO.setDeviceName(device.getDeviceName());
        cusDeviceBreakdownDTO.setDeviceLocation(device.getDeviceLocation());
        SysDictionary deviceType = sysDictionaryService.getById(device.getDeviceType());
        cusDeviceBreakdownDTO.setDeviceTypeName(deviceType.getDicName());

        //任务等级
        SysDictionary dictionary = sysDictionaryService.getById(entity.getBreakdownLevel());
        if(dictionary!=null){
            cusDeviceBreakdownDTO.setBreakdownLevelName(dictionary.getDicName());
        }
        //维修责任人
        SysUser user = sysUserService.getById(entity.getRepaireUserId());
        if(user!=null){
            cusDeviceBreakdownDTO.setRepaireUserName(user.getRealName());
        }
        //照片列表
        QueryWrapper queryWrapper = new QueryWrapper<>();
        queryWrapper.select("document_id");
        queryWrapper.eq("device_ref_id",entity.getId());
        queryWrapper.eq("device_ref_type",Const.DeviceRefType.DEVICE_BREAKDOWN_FILE);
        List<CusDocument> documentList = cusDocumentService.list(queryWrapper);
        cusDeviceBreakdownDTO.setCusDocumentListDocument(documentList);
        // 图片列表
        if(CollectionUtil.isNotEmpty(documentList)){
            List<Integer> fileIds = documentList.stream()
                    .map(CusDocument::getDocumentId)
                    .collect(Collectors.toList());
            QueryWrapper queryFileWrapper = new QueryWrapper<>();
            queryFileWrapper.in("id",fileIds);
            List<SysFileHis> fileHisList = sysFileHisService.list(queryFileWrapper);
            cusDeviceBreakdownDTO.setSysFileHisList(fileHisList);
        }


        CusRepaireDTO cusRepaireDTO = new CusRepaireDTO();
        cusBreakDownRepaireDTO.setCusRepaireDTO(cusRepaireDTO);

        BeanUtils.copyProperties(repair,cusRepaireDTO);
        cusRepaireDTO.setId(repair.getId());
        cusRepaireDTO.setUseStatusName(sysDictionaryService.getById(repair.getUseStatus()).getDicName());

        //获取备件列表
        List<CusRepaireSpareVo> cusRepaireSpareVoList =  cusRepaireSpareService.findListByParam(id);
        cusRepaireDTO.setCusRepaireSpareList(cusRepaireSpareVoList);

        //照片列表
        QueryWrapper queryWrapper2 = new QueryWrapper<>();
        queryWrapper2.select("document_id");
        queryWrapper2.eq("device_ref_id",repair.getId());
        queryWrapper2.eq("device_ref_type",Const.DeviceRefType.DEVICE_REPAIR_FILE);
        List<CusDocument> documentList2 = cusDocumentService.list(queryWrapper2);
        cusRepaireDTO.setCusDocumentListDocument(documentList2);
        // 图片列表
        if(CollectionUtil.isNotEmpty(documentList2)){
            List<Integer> fileIds = documentList2.stream()
                    .map(CusDocument::getDocumentId)
                    .collect(Collectors.toList());
            QueryWrapper queryFileWrapper = new QueryWrapper<>();
            queryFileWrapper.in("id",fileIds);
            List<SysFileHis> fileHisList = sysFileHisService.list(queryFileWrapper);
            cusRepaireDTO.setSysFileHisList(fileHisList);
        }

        return cusBreakDownRepaireDTO;
    }








    @Override
    public void del(List<Integer> ids) {
        // 校验状态
        QueryWrapper queryWrapperBreakDown = new QueryWrapper<>();
        queryWrapperBreakDown.select("id");
        queryWrapperBreakDown.in("id",ids);
        queryWrapperBreakDown.ne("repaire_status",Const.RepairRecordStatus.PROCESSING);
        List list = this.list(queryWrapperBreakDown);
        if(list.size()!=0){
            throw new BDException("操作失败，只能删除暂存的故障报修！");
        }

        //删除维修记录
        removeByIds(ids);
        //删除图片关系
        QueryWrapper queryWrapper = new QueryWrapper<>();
        queryWrapper.in("device_ref_id",ids);
        queryWrapper.eq("device_ref_type",Const.DeviceRefType.DEVICE_REPAIR_FILE);
        cusDocumentService.remove(queryWrapper);

        //删除备件关系
        QueryWrapper queryWrapper2 = new QueryWrapper<>();
        queryWrapper2.in("repaire_id",ids);
        cusRepaireSpareService.remove(queryWrapper2);

    }

    @Override
    public IPage<CusRepaireVo> findPageListByParam(CusRepairePageParam param) {
        //分页
        Page<CusRepaireVo> page = new Page<>(param.getCurrentPage(), param.getPageSize());
        //查询分页
        IPage<CusRepaireVo> pageList = this.baseMapper.findListByParam(page, param);

        return pageList;
    }

    @Override
    public List<CusRepaireVo> findListByBreakDownId(Integer breakDownId) {

        CusRepairePageParam param = new CusRepairePageParam();
        param.setBreakDownId(breakDownId);

        //查询列表
        List<CusRepaireVo> pageList = this.baseMapper.findListByParam(param);

        return pageList;
    }

    @Override
    public List<CusRepaireVo> findListByParam(CusRepairePageParam cusDeviceRepairePageParam) {
        //不分页
        List<CusRepaireVo> cusRepaireVoList = this.baseMapper.findListByParam(cusDeviceRepairePageParam);
        //返回值
        return cusRepaireVoList;
    }

    /**
     * 同步设备使用状况
     * @param repair
     */
    private void updateDeviceUseStatus(CusRepaire repair){
        CusDeviceBreakdown cusDeviceBreakdown = cusDeviceBreakdownService.getById(repair.getBreakdownId());
        if(cusDeviceBreakdown!=null && Objects.equals(cusDeviceBreakdown.getRepaireStatus(),Const.RepairStatus.PROCESSED_ACCEPTANCE)){

            Integer deviceId = cusDeviceBreakdown.getDeviceId();
            CusDevice device = cusDeviceService.getById(deviceId);

            device.setUseStatus(repair.getUseStatus());
            cusDeviceService.updateById(device);
        }
    }


}




